import pybarb as pb
import json
import plotly.io as pio
pio.renderers.default = "plotly_mimetype+notebook"
# Read in Barb API credentials
with open("/Users/simon_business/Documents/disposable/clients/BARB/creds.json") as file:
creds = json.load(file)
# Create a BarbAPI object and connect
barb_api = pb.BarbAPI(creds)
barb_api.connect()
%load_ext autoreload
%autoreload 2Getting started
Create a connection to the Barb API
This code uses your account details to get an access token from the API. Your creds.json file should include the email and password supplied by BARB. For example:
{"email": "me@coppelia.io", "password": "INSERT PASSWORD"}
Querying an endpoint
There are (at present) three endpoint methods: programme_ratings, advertising_spots and audiences_by_time. Query parameters can be supplied as arguments to the function. See the Barb API documentation for the available query parameters.
Example: querying the programme_ratings endpoint
Here we get the audience figures for all programs shown on BBC 1 to the BBC Network panel between 2020-01-01 and 2020-01-03.
bbc_1_progs = barb_api.programme_ratings(min_transmission_date = "2020-01-01",
max_transmission_date = "2020-01-03",
station="BBC1", panel="bbc network",
consolidated=True)
bbc_1_progs.to_dataframe()| panel_region | station_name | programme_name | programme_type | programme_start_datetime | programme_duration_minutes | spans_normal_day | uk_premiere | broadcaster_premiere | programme_repeat | episode_number | episode_name | genre | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 1032 | 2020-01-02 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 1243 | 2020-01-02 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 740 | 2020-01-02 | All Men | 251740 |
| 3 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 893 | 2020-01-02 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 0 | 2020-01-02 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 11813 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 0 | 2020-01-03 | Boys 10-12 | 12300 |
| 11814 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 1332 | 2020-01-03 | Adults, Lightest Third | 170290 |
| 11815 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 190 | 2020-01-03 | Adults, Lightest Sixth | 85160 |
| 11816 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 865 | 2020-01-03 | ABC1 Adults, Lightest Third | 94760 |
| 11817 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 71 | 2020-01-03 | Adults 16-34, Lightest Third | 47620 |
11818 rows × 17 columns
To find the right station or panel name you can use the list_stations() and list_panels() methods. You can use any regex string as an argument.
barb_api.list_stations("ITV")['ITV1',
'ITV1 HD',
'ITV1+1',
'ITV4+1',
'ITV Play',
'ITV2+1',
'ITV3+1',
'ITV3',
'ITV4',
'CITV',
'ITV Sport',
'ITV Sport Select',
'ITV2',
'ITV2 HD',
'ITV Encore',
'ITV Encore +1',
'ITVBe',
'ITVBe +1']
barb_api.list_panels("BBC")['BBC Network',
'BBC East Region',
'BBC West Region',
'BBC South West Region',
'BBC South Region',
'BBC Yorkshire & Lincolnshire',
'BBC North East & Cumbria',
'BBC North West Region',
'BBC Scotland Region',
'BBC Ulster Region',
'BBC Wales Region',
'BBC Midlands West',
'BBC Midlands East',
'BBC London',
'BBC South East']
Example: querying the advertising spots endpoint
Here we get all advertising spots placed on ITV 1 by Mediacom Dublin between 2020-01-01 and 2020-01-03.
itv_1_spots = barb_api.advertising_spots("2020-01-01", "2020-01-02",
station="ITV1", panel="bbc network",
consolidated=True, limit=5000)
itv_1_spots.to_dataframe()| panel_region | station_name | spot_type | spot_start_datetime | spot_duration | preceding_programme_name | succeeding_programme_name | break_type | position_in_break | broadcaster_spot_number | ... | clearcast_buyer_code | clearcast_buyer_name | clearcast_advertiser_code | clearcast_advertiser_name | campaign_approval_id | sales_house_name | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Homes | 269200 |
| 1 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Adults | 510930 |
| 2 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Houseperson | 269200 |
| 3 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | Adults 55-64 | 81070 |
| 4 | BBC Network | ITV | spot | 2020-01-01 08:37:47 | 20 | THE RUBBISH WORLD OF DAVE SPUD | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60265037 | ... | B001030 | HAVAS MEDIA | A004063 | DREAMS | 868653.0 | ITV Breakfast | 283 | 2020-01-01 | All Homes | 269200 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3326 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 680 | 2020-01-02 | Houseperson working full-time | 105330 |
| 3327 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 143 | 2020-01-02 | Men ABC1 working full-time | 87120 |
| 3328 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 39 | 2020-01-02 | Men AB working full-time | 43400 |
| 3329 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 189 | 2020-01-02 | Houseperson with children 0-15 | 70140 |
| 3330 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 35 | 2020-01-02 | Houseperson with children 0-3 | 25210 |
3331 rows × 24 columns
We can use the list_buyers and list_advertisers methods to look up the correct names.
barb_api.list_buyers("mediacom")['essence_mediacom_drt',
'essence_mediacom_hol',
'essence_mediacom_nor',
'essencemediacom',
'mediacom_dublin',
'mediacom_holdings_li',
'mediacom_ireland_(no',
'mediacom_media_plann',
'mediacom_north_limit',
'mediacom_scotland_li']
Example: querying the audiences_by_time endpoint
Here we use the audiences_by_time endpoint to bring back viewing on BBC 1 in 15 minute segments, where the viewing has been on the same day as live (vosdal).
bbc_1_by_time = barb_api.audiences_by_time("2020-01-01", "2020-01-03", time_period_length=15,
viewing_status = 'vosdal',
station="BBC1", panel="bbc network")
bbc_1_by_time.to_dataframe()| panel_region | station_name | date_of_transmission | activity | transmission_time_period_start | audience_size_hundreds | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 4018 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 6964 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 3494 | All Men | 251740 |
| 3 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 3647 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 234 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 15684 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 47 | Houseperson with children 0-3 | 25210 |
| 15685 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 157 | Adults, Lightest Third | 170290 |
| 15686 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 74 | Adults, Lightest Sixth | 85160 |
| 15687 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 71 | ABC1 Adults, Lightest Third | 94760 |
| 15688 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 36 | Adults 16-34, Lightest Third | 47620 |
15689 rows × 8 columns
Data conversion
The raw json is stored in the api_response_data attribute of the BarbAPI object
However it is much easier to use the various data conversion methods. For example to convert to a data frame we use:
bbc_1_progs.to_dataframe()| panel_region | station_name | programme_name | programme_type | programme_start_datetime | programme_duration_minutes | spans_normal_day | uk_premiere | broadcaster_premiere | programme_repeat | episode_number | episode_name | genre | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 1032 | 2020-01-02 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 1243 | 2020-01-02 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 740 | 2020-01-02 | All Men | 251740 |
| 3 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 893 | 2020-01-02 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | Weather for the Week Ahead: Series 2020 | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 0 | 2020-01-02 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 11813 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 0 | 2020-01-03 | Boys 10-12 | 12300 |
| 11814 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 1332 | 2020-01-03 | Adults, Lightest Third | 170290 |
| 11815 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 190 | 2020-01-03 | Adults, Lightest Sixth | 85160 |
| 11816 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 865 | 2020-01-03 | ABC1 Adults, Lightest Third | 94760 |
| 11817 | BBC Network | BBC1 | BBC London | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 71 | 2020-01-03 | Adults 16-34, Lightest Third | 47620 |
11818 rows × 17 columns
You can also use to_csv(), to_excel() and to_json() and to_sql to save to csv files, excel files, json files and to a database.
These can be chained with the query like this
barb_api.programme_ratings("2020-01-01", "2020-01-03",
station="BBC1", panel="bbc network",
consolidated=True).to_excel("programme_ratings.xlsx")Pivoting the data by audience
For all three endpoints, we can use the audience_pivot() method to produce a dataframe where the audience categories are given in columns. Note the audiences will be summed in each cell.
barb_api.advertising_spots("2020-01-01", "2020-01-02",
station="ITV1", panel="bbc network",
consolidated=True, limit=5000).audience_pivot()| audience_name | ABC1 Adults, Lightest Third | Adults 16-24 | Adults 16-34 | Adults 16-34, Lightest Third | Adults 35-44 | Adults 45-49 | Adults 45-54 | Adults 55-64 | Adults AB | Adults ABC1 | ... | Men AB | Men AB working full-time | Men ABC1 | Men ABC1 16-24 | Men ABC1 16-34 | Men ABC1 16-44 | Men ABC1 35-54 | Men ABC1 working full-time | Men C2 | Men working full-time | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| panel_region | station_name | date_of_transmission | clearcast_commercial_title | |||||||||||||||||||||
| BBC Network | ITV | 2020-01-01 | 30 Tuesday clocked | 0.0 | 0.0 | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 151.0 | 0.0 | 14.0 | ... | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 14.0 | 14.0 | 14.0 | 0.0 | 14.0 |
| 30AWC2Grand Sofa CaperGrand SaleNow o | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 65.0 | 114.0 | ... | 65.0 | 0.0 | 65.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | |||
| BEPD Ends Tues 10D | 9.0 | 196.0 | 377.0 | 196.0 | 127.0 | 0.0 | 400.0 | 0.0 | 217.0 | 373.0 | ... | 96.0 | 96.0 | 157.0 | 0.0 | 96.0 | 110.0 | 44.0 | 110.0 | 471.0 | 384.0 | |||
| BEPD Ends Tues 20A | 0.0 | 0.0 | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 179.0 | 52.0 | 240.0 | ... | 0.0 | 0.0 | 108.0 | 0.0 | 0.0 | 14.0 | 14.0 | 14.0 | 0.0 | 14.0 | |||
| BEPD Ends Tues 20B | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 190.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 43.0 | 0.0 | |||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ||
| 2020-01-02 | Tails Lorraine Collab 30 | 132.0 | 84.0 | 132.0 | 132.0 | 553.0 | 410.0 | 714.0 | 881.0 | 113.0 | 1266.0 | ... | 84.0 | 0.0 | 334.0 | 84.0 | 84.0 | 84.0 | 0.0 | 54.0 | 165.0 | 359.0 | ||
| Virgin Holidays Peak Sale Couples | 69.0 | 0.0 | 50.0 | 0.0 | 521.0 | 113.0 | 500.0 | 1241.0 | 238.0 | 1375.0 | ... | 120.0 | 120.0 | 427.0 | 0.0 | 0.0 | 120.0 | 187.0 | 187.0 | 343.0 | 682.0 | |||
| Week 14 From Boxing Day Biggest ever sale | 0.0 | 0.0 | 147.0 | 0.0 | 338.0 | 147.0 | 491.0 | 1012.0 | 73.0 | 1272.0 | ... | 0.0 | 0.0 | 359.0 | 0.0 | 41.0 | 41.0 | 67.0 | 254.0 | 53.0 | 413.0 | |||
| Wonder 2019 10 | 69.0 | 0.0 | 135.0 | 0.0 | 1371.0 | 581.0 | 1796.0 | 3065.0 | 472.0 | 3729.0 | ... | 144.0 | 144.0 | 965.0 | 0.0 | 0.0 | 144.0 | 345.0 | 491.0 | 703.0 | 1363.0 | |||
| myWW TVC 30 alternative intro same o | 132.0 | 84.0 | 132.0 | 132.0 | 591.0 | 410.0 | 714.0 | 942.0 | 150.0 | 1304.0 | ... | 121.0 | 37.0 | 371.0 | 84.0 | 84.0 | 121.0 | 37.0 | 91.0 | 200.0 | 431.0 |
90 rows × 55 columns
Time series plots
Interactive time series plots are available on all three endpoints.
barb_api.audiences_by_time("2020-01-01", "2020-01-31", time_period_length=15, viewing_status = 'vosdal',
station="BBC1", panel="bbc network").ts_plot()Querying viewing data using the asynchronous API
We would like one day’s worth of viewing data (2023-07-06) for BBC1 East viewing station and the BBC East Region panel.
First we need to look up the viewing station and panels to check we have the correct query parameters
barb_api.list_panels("BBC")['BBC Network',
'BBC East Region',
'BBC West Region',
'BBC South West Region',
'BBC South Region',
'BBC Yorkshire & Lincolnshire',
'BBC North East & Cumbria',
'BBC North West Region',
'BBC Scotland Region',
'BBC Ulster Region',
'BBC Wales Region',
'BBC Midlands West',
'BBC Midlands East',
'BBC London',
'BBC South East']
barb_api.list_viewing_stations("BBC1")['BBC1 Midlands West',
'BBC1 East',
'BBC1 West',
'BBC1 South West',
'BBC1 South',
'BBC1 Yorks/Lincs',
'BBC1 North East/Cumbria',
'BBC1 North West',
'BBC1 Scotland',
'BBC1 Wales',
'BBC1 Northern Ireland',
'BBC1 Midlands East',
'BBC1 London',
'BBC1 South East']
Next we need to request the data sets from the asynchronous API. We will use the pybarb package to do this.
barb_api.viewing(min_session_date="2023-07-06", max_session_date="2023-07-06",
viewing_station="BBC1 East", panel="BBC East Region")Job successfully started. The job id is b0a71da8-9701-4cd4-ae55-8f9f034e5177
Once the job has started we can use the ping_job_status method to check the status of the job. It will check the status every 60 seconds until the job is complete.
barb_api.ping_job_status()Job not ready yet. Sleeping for 60 seconds.
Job not ready yet. Sleeping for 60 seconds.
Job complete. 1 files are ready for download.
Now we can download the data using the get_asynch_files method.
viewing_results_set = barb_api.get_asynch_files()In its raw form we can see many of the cells contain json. We will need to unpack this.
viewing_results_set.api_response_data.head(5)| STANDARD_DATE_OF_ACTIVITY | SESSION_START | SESSION_END | HOUSEHOLD | DEVICE | PANEL_VIEWERS | GUEST_VIEWERS | PROGRAMMES_VIEWED | SPOTS_VIEWED | VIEWING_STATION | ... | PLATFORM | ACTIVITY_TYPE | CONTENT_ASSET_ITEM_OFFSET | PLAYBACK_TYPE | SKY_ULTRA_HD | START_OF_RECORDING | TARGETED_PROMOTION | VOD_INDICATOR | VOD_PROVIDER | REPLICATE_ID | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-07-06 | {'barb_polling_datetime': '2023-07-06 03:45:00... | {'barb_polling_datetime': '2023-07-06 04:46:00... | {'bbc_itv_segment': 'bbc east / east of englan... | {'date_valid_for': '2023-07-06', 'device_numbe... | [{'date_of_birth': '1990-08-01', 'dependency_o... | {} | [{'broadcaster_premier': True, 'broadcaster_tr... | [] | {'viewing_station_code': 32, 'viewing_station_... | ... | digital terrestrial | live viewing (excl targeted advertising) | 0 | unknown | False | {} | False | not on-demand | {'vod_provider': 'unknown', 'vod_service': 'un... | None |
| 1 | 2023-07-06 | {'barb_polling_datetime': '2023-07-06 18:04:00... | {'barb_polling_datetime': '2023-07-06 18:07:00... | {'bbc_itv_segment': 'bbc east / east of englan... | {'date_valid_for': '2023-07-06', 'device_numbe... | [{'date_of_birth': '1948-10-01', 'dependency_o... | {'female_45_64': 1, 'male_45_64': 1} | [{'broadcaster_premier': True, 'broadcaster_tr... | [] | {'viewing_station_code': 32, 'viewing_station_... | ... | digital terrestrial | live viewing (excl targeted advertising) | 0 | unknown | False | {} | False | not on-demand | {'vod_provider': 'unknown', 'vod_service': 'un... | None |
| 2 | 2023-07-06 | {'barb_polling_datetime': '2023-07-06 20:55:00... | {'barb_polling_datetime': '2023-07-06 22:45:00... | {'bbc_itv_segment': 'bbc east / east of englan... | {'date_valid_for': '2023-07-06', 'device_numbe... | [{'date_of_birth': '1947-04-01', 'dependency_o... | {} | [{'broadcaster_premier': True, 'broadcaster_tr... | [] | {'viewing_station_code': 32, 'viewing_station_... | ... | digital terrestrial | live viewing (excl targeted advertising) | 0 | unknown | False | {} | False | not on-demand | {'vod_provider': 'unknown', 'vod_service': 'un... | None |
| 3 | 2023-07-06 | {'barb_polling_datetime': '2023-07-06 06:07:00... | {'barb_polling_datetime': '2023-07-06 08:18:00... | {'bbc_itv_segment': 'bbc east / east of englan... | {'date_valid_for': '2023-07-06', 'device_numbe... | [{'date_of_birth': '1948-05-01', 'dependency_o... | {} | [{'broadcaster_premier': True, 'broadcaster_tr... | [] | {'viewing_station_code': 32, 'viewing_station_... | ... | digital satellite | live viewing (excl targeted advertising) | 0 | unknown | False | {} | False | not on-demand | {'vod_provider': 'unknown', 'vod_service': 'un... | None |
| 4 | 2023-07-06 | {'barb_polling_datetime': '2023-07-06 21:59:00... | {'barb_polling_datetime': '2023-07-06 22:02:00... | {'bbc_itv_segment': 'bbc east / east of englan... | {'date_valid_for': '2023-07-06', 'device_numbe... | [{'date_of_birth': '1948-05-01', 'dependency_o... | {} | [{'broadcaster_premier': True, 'broadcaster_tr... | [] | {'viewing_station_code': 32, 'viewing_station_... | ... | digital satellite | live viewing (excl targeted advertising) | 0 | unknown | False | {} | False | not on-demand | {'vod_provider': 'unknown', 'vod_service': 'un... | None |
5 rows × 21 columns
We can either save it as json using the to_json method…
viewing_results_set.to_json("results.json")Or we can use the to_dataframe method to reshape the data so that we have one row per viewer per programme.
df = viewing_results_set.to_dataframe(unpack=["viewers", "programmes"])
df.head()| programme_start_datetime | programme_name | date_of_birth | dependency_of_children | disability | ethnic_origin | gaelic_language | household_status | life_stage | marital_status | ... | number_of_tv_sets | number_of_vcrs | panel_membership_status | presence_of_children | replication_factor | social_class | welsh_speaking_home | device_number | device_on_panel | device_type | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-07-06 01:33:57 | Joins BBC News: Series 2023 | 1990-08-01 | unclassified | no | white british | not gaelic speaking/not in scotland | neither houseperson nor head of household | single no children with parents aged 16-34 | single / divorced / separated | ... | 2 | 0 | home on panel (valid reporter) | no children | 24 | D | non welsh speaking | 2 | True | tv |
| 4 | 2023-07-06 18:00:03 | BBC News at Six: Series 2023 | 1948-10-01 | unclassified | yes limited a little | white british | not gaelic speaking/not in scotland | houseperson and not Head of household | couple no children aged 55+ | married / living as married | ... | 1 | 0 | home on panel (valid reporter) | no children | 21 | AB | non welsh speaking | 1 | True | tv |
| 8 | 2023-07-06 18:59:42 | Wimbledon: Series 2023 | 1947-04-01 | unclassified | no | white british | not gaelic speaking/not in scotland | both houseperson and head of household | single no children on own aged 55+ | single / divorced / separated | ... | 1 | 0 | home on panel (valid reporter) | no children | 8 | AB | non welsh speaking | 1 | True | tv |
| 12 | 2023-07-06 06:00:00 | Breakfast: Series 2023 | 1948-05-01 | unclassified | no | white british | not gaelic speaking/not in scotland | both houseperson and head of household | single no children on own aged 55+ | single / divorced / separated | ... | 2 | 0 | home on panel (valid reporter) | no children | 5 | C1 | non welsh speaking | 1 | True | tv |
| 16 | 2023-07-06 18:59:42 | Wimbledon: Series 2023 | 1948-05-01 | unclassified | no | white british | not gaelic speaking/not in scotland | both houseperson and head of household | single no children on own aged 55+ | single / divorced / separated | ... | 2 | 0 | home on panel (valid reporter) | no children | 5 | C1 | non welsh speaking | 1 | True | tv |
5 rows × 43 columns